home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / demograph / data.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  359 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include "stdio.h"
  18. #include "ctype.h"
  19. #include "math.h"
  20. #include "malloc.h"
  21. #include "demograph.h"
  22.  
  23. typedef struct {
  24.     char title[MAXTITLE];
  25.     float firstyear;
  26.     float nvalues;
  27.     float monthspan;
  28.     float maxvalue;
  29.     float minvalue;
  30.     float *values;
  31. } FILEDATA;
  32.  
  33. #define DBUG FALSE
  34.  
  35. char *montharray[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
  36. "Sep","Oct","Nov","Dec"};
  37.  
  38.  
  39. extern CATEGORY *categoryroot, *curcategory;
  40. extern usage[];
  41.  
  42. /* GETDATA gets the data from the listed data files */
  43. getdata(argc, argv)
  44. int argc;
  45. char *argv[];
  46. {
  47.     FILE           *file;
  48.     int             i, lnum, fct;
  49.  
  50.     int readata(FILE *file, char *filename);
  51.  
  52.     FILE *openfile(char *arg, char *readwrite);
  53.  
  54.     if (argc < 2) {
  55.     fprintf(stderr,"%s",usage);
  56.     exit(1);
  57.     }
  58.     fct = 0;
  59.     for (i = 1; i < argc; i++) {
  60.     if (strcmp("-s",argv[i]) == 0) {
  61.         i++;
  62.         continue;
  63.     }
  64.     if (strcmp("-f",argv[i]) == 0) {
  65.         continue;
  66.     }
  67.     
  68.     file = openfile(argv[i],"r");
  69.     
  70.     if ((lnum = readdata(file, argv[i])) != 0)
  71.         fprintf(stderr, "error in data file: %s line %d\n", argv[i], lnum);
  72.         /* no error returned from categories, so do not need to clean up */
  73.     else
  74.         fct++;
  75.     }
  76.  
  77.     /* fprintf (stderr,"rct=%d\n",fct); */
  78.     if (fct == 0) {
  79.     fprintf(stderr,"%s",usage);
  80.     exit(1);
  81.     }
  82.  
  83.     curcategory = categoryroot;    
  84. }
  85.  
  86.  
  87. /* READDATA reads the information from a data file.  The first non commented
  88.    line in a file has to match the demographic magic number.  The next non
  89.    comment line must contain the title of the data.  The next non commented
  90.    line contains three integers:  the first year of the data, number of data
  91.    entrys per state, and the time between entrys in months.  These three data
  92.    items are separated by spaces.  Each successive line following contains a
  93.    data list for one of 49 states (including the District of Columbia) in
  94.    alphabetical order.  Comments are contained on a sinle line and the first
  95.    character of a comment line is '#'. 
  96. */  
  97. int readdata(file, filename)
  98. FILE *file;
  99. char *filename;
  100. {
  101.     FILEDATA        filedata;
  102.     char            string[MAXSTRING];
  103.     float          *curvalue;
  104.     int             magic;
  105.     int             s, v;
  106.     long            lnum;
  107.     char *strptr, *oldptr;
  108.     char *chr;
  109.  
  110.     int readln(FILE *file, char *string, long *lnum);
  111.     void make_lookup_table(FILEDATA filedata);
  112.  
  113.     /* get next non comment line */
  114.     if (readln(file, string, &lnum) <= 0)
  115.     return (lnum);
  116.  
  117.     /* check for magic number (to check file type) */
  118.     if (sscanf(string, "%d", &magic) != 1 || magic != MAGIC) {
  119.     fprintf(stderr, "file is not a demographic data file: %s\n", filename);
  120.     return (lnum);
  121.     }
  122.  
  123.     /* get next non comment line */
  124.     if (readln(file, string, &lnum) <= 0)
  125.     return (lnum);
  126.  
  127.     /* get data title (need to remove '\n') */
  128.     if (strlen(strncpy(filedata.title, string, MAXTITLE)) >= MAXTITLE) {
  129.     filedata.title[MAXTITLE - 1] = '\0';
  130.     }
  131.     chr=filedata.title;
  132.     while (*chr != '\n' && *chr != '\0') {
  133.     chr++;
  134.     }
  135.     if (*chr == '\n') {
  136.     *chr = '\0';
  137.     } 
  138.  
  139.     /* get next non comment line */
  140.     if (readln(file, string, &lnum) <= 0)
  141.     return (lnum);
  142.  
  143.     /* get data parameters */
  144.     if (sscanf(string, "%f %f %f", &filedata.firstyear, &filedata.nvalues,
  145.            &filedata.monthspan) != 3) {
  146.     return (lnum);
  147.     }
  148.  
  149.     /* make room for data structure */
  150.     if (DBUG) fprintf(stderr,"\nmallocing (%d*%d*%d)=%d bytes\n",
  151.     (int)filedata.nvalues,NUMSTATES,sizeof(float),
  152.     (int)filedata.nvalues * NUMSTATES * sizeof(float));
  153.  
  154.     if ((filedata.values = (float *) malloc((int)filedata.nvalues * NUMSTATES *
  155.                         sizeof(float))) == NULL) {
  156.     fprintf(stderr, "error in memory allocation 1\n");
  157.     exit(1);
  158.     }
  159.  
  160.     /* init min and max data values */
  161.     filedata.maxvalue = 0.0;
  162.     filedata.minvalue = 4294967296.0;    /* 2^^32 large number */
  163.  
  164.     /* get the data for each state */
  165.     curvalue = filedata.values;
  166.     for (s = 0; s < NUMSTATES; s++) {
  167.  
  168.     /* get next non comment line */
  169.     if (readln(file, string, &lnum) <= 0) {
  170.         free(filedata.values);
  171.         filedata.values = NULL;
  172.         return (lnum);
  173.     }
  174.     /* pointer to parse numbers in file */
  175.     strptr = &string[0];
  176.  
  177.     for (v = 0; v < filedata.nvalues; v++) {
  178.         /*
  179.          * get next number in string. if not enough numbers return
  180.          * error 
  181.          */
  182.         oldptr = strptr;
  183.         *curvalue = (float)strtod(strptr,&strptr);
  184.         if (strptr == oldptr) {    /* not enough data on line */
  185.         free(filedata.values);
  186.         filedata.values = NULL;
  187.         return (lnum);
  188.         }
  189.  
  190.         /* get the max and min values for scaling */
  191.         if (*curvalue > filedata.maxvalue)
  192.         filedata.maxvalue = *curvalue;
  193.         if (*curvalue < filedata.minvalue)
  194.         filedata.minvalue = *curvalue;
  195.  
  196.         if (DBUG) fprintf(stderr,"%.1f ",*curvalue);
  197.  
  198.         curvalue++;
  199.  
  200.     }
  201.     if (DBUG) fprintf(stderr,"\n");
  202.     }
  203.  
  204.     make_lookup_table(filedata);
  205.     free(filedata.values);
  206.     filedata.values = NULL;
  207.  
  208.     /* if no errors return 0 */
  209.     return (0);
  210. }
  211.  
  212.  
  213. /* READLN gets the next line of non commented text.
  214. */
  215. int readln(file,string,lnct)
  216. FILE *file;
  217. char *string;
  218. long *lnct;
  219. {
  220.     char            c;
  221.  
  222.     do {
  223.     (*lnct)++;
  224.  
  225.     /* check for end of file - return 0 */
  226.     if (fgets(string, MAXSTRING, file) == NULL)
  227.         return (0);
  228.  
  229.     /* check for error - return negative */
  230.     if (sscanf(string, "%c", &c) == 0)
  231.         return (-1);
  232.  
  233.     } while (c == '#' || c == '\n');
  234.  
  235.     /* all is well - return positive */
  236.     return (1);
  237. }
  238.  
  239.  
  240. /* MAKE_LOOKUP_TABLE makes a lookup table of size MAXDATA (based on the screen
  241.    size) associated with a demographic category (file).  This table will be
  242.    indexed based on the slider bar position.  Each data entry contains a date
  243.    and a list of values for each state associated with that date.
  244.  */
  245. void make_lookup_table(filedata)
  246. FILEDATA filedata;
  247. {
  248.     if (DBUG)
  249.     fprintf(stderr, "\nmallocing %d bytes\n", sizeof(CATEGORY));
  250.  
  251.     /* allocate space for this file (category) */
  252.     if (categoryroot == NULL) {
  253.     if ((categoryroot = (CATEGORY *) malloc(sizeof(CATEGORY))) == NULL) {
  254.         fprintf(stderr, "error in memory allocation 2\n");
  255.         exit(1);
  256.     }
  257.     curcategory = categoryroot;
  258.     } else {
  259.     if ((curcategory->next=(CATEGORY *)malloc(sizeof(CATEGORY))) == NULL) {
  260.         fprintf(stderr, "error in memory allocation\n");
  261.         exit(1);
  262.     } else {
  263.         curcategory = curcategory->next;
  264.     }
  265.     }
  266.  
  267.     curcategory->next = NULL;
  268.  
  269.     /* length checked when we read in the title */
  270.     strcpy(curcategory->title, filedata.title);
  271.     if (DBUG)
  272.     fprintf(stderr, "%s\n", curcategory->title);
  273.  
  274.     if (DBUG)
  275.     fprintf(stderr, "%f\n", curcategory->scale);
  276.  
  277.     /*
  278.      * expand data to fill in (presumably) larger data array for quick
  279.      * index this takes more memory, but saves computation during display. 
  280.      * This will definitely be graphics (and memory) intensive 
  281.      */
  282.     {
  283.     register int    iindex;
  284.     register int    d;
  285.     register int    i;
  286.     register int    dayinc =(int) filedata.nvalues;
  287.     register float *valueptr;
  288.     register float *today;
  289.     register float *tomorrow;
  290.     register DATA  *dataptr = curcategory->dataarray;
  291.  
  292.     float           year;
  293.     float           month;
  294.     float           findex;
  295.     float           firstyear = filedata.firstyear;
  296.     float           monthspan = filedata.monthspan / 12.0;
  297.     float           ndatarecs = MAXDATA - 1;
  298.     float           ndatavals = filedata.nvalues - 1;
  299.     float offset = filedata.minvalue;
  300.     float scale = 1.0 / (filedata.maxvalue - filedata.minvalue);
  301.  
  302.  
  303.  
  304. #ifdef DBUG
  305.     int             datacount = 0;
  306. #endif
  307.  
  308.     /* fprintf(stderr,"min%f max%f o%f s%f \n",
  309.         filedata.minvalue, filedata.maxvalue, offset, scale);
  310.     */
  311.     for (d = 0; d < MAXDATA; d++) {
  312.  
  313.         findex = d * ndatavals / ndatarecs;
  314.         iindex = (int) findex;
  315.  
  316.         year = firstyear + findex * monthspan;
  317.         findex -= iindex;
  318.         month = findex * 12.0;
  319.  
  320.         sprintf(dataptr->date, "%s %d",montharray[(int)month],(int)year);
  321.         if (DBUG)
  322.         fprintf(stderr, "%s\n", dataptr->date);
  323.  
  324.         today = filedata.values + iindex;
  325.         tomorrow = (iindex == ndatavals) ? today : today + 1;
  326.         valueptr = dataptr->data;
  327.  
  328.         for (i = 0; i < NUMSTATES; i++) {
  329.  
  330.         *valueptr = *today + (*tomorrow - *today) * findex;
  331.  
  332.         /* normalize value */
  333.         /* fprintf (stderr,"v1=%f o=%f s=%f ",
  334.             *valueptr, offset, scale); */
  335.         *valueptr = (*valueptr - offset) * scale;
  336.         /* fprintf (stderr,"v2=%f\n",*valueptr); */
  337.         valueptr++;
  338.  
  339.         if (DBUG) {
  340.             fprintf(stderr," %.3f ",*today+(*tomorrow-*today)*findex); 
  341.             datacount++;
  342.             if ((datacount % 16) == 0)
  343.             fprintf(stderr, "\n");
  344.         }
  345.  
  346.         today += dayinc;
  347.         tomorrow += dayinc;
  348.         }
  349.  
  350.         if (DBUG) {
  351.         fprintf(stderr, "\n\n");
  352.         datacount = 0;
  353.         }
  354.         dataptr++;
  355.     }
  356.     }
  357. }
  358.     
  359.